/**
 * 
 */
package edu.rice.myxo.utils;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import edu.rice.myxo.sim.Global;

/**
 * @author Haiyang Zhang
 * 
 */
public class MathUtils {

	/**
	 * Check if value falls in (low,high) range
	 * 
	 * @param value
	 * @param low
	 * @param high
	 * @return
	 */
	public static boolean inRange(double value, double low, double high) {
		return value > low && value < high;
	}

	/**
	 * Check if the point (value1,value2) falls in the rectangle range(low1,
	 * low2, high1, high2).
	 * 
	 * @param value1
	 * @param value2
	 * @param low1
	 * @param low2
	 * @param high1
	 * @param high2
	 * @return
	 */
	public static boolean inRange2(double value1, double value2, double low1,
			double low2, double high1, double high2) {
		return inRange(value1, low1, high1) && inRange(value2, low2, high2);
	}

	/**
	 * Test if the angle test is in the range of (center-range,center+range).
	 * The maxValue could be 2pi or pi.
	 * 
	 * @param center
	 * @param range
	 * @param test
	 * @param maxValue
	 * @return
	 */
	public static boolean inAngelRange(double center, double range,
			double test, double maxValue) {
		double up = center + range;
		double down = center - range;
		boolean ifin = false;
		if (up > maxValue) {
			ifin = (test > 0 && test < (up - maxValue))
					|| (test > down && test < maxValue);
		} else if (down < 0) {
			ifin = (test > 0 && test < up)
					|| (test > down + maxValue && test < maxValue);
		} else {
			ifin = test > down && test < up;
		}
		return ifin;
	}

	/**
	 * Return if the line (p1,p2), intersect with line(p3,p4) The intersection
	 * point is stored in isPt
	 * http://www.javaworld.com/jw-04-2001/jw-0406-jmf1.html?page=5
	 * 
	 * @param p1
	 * @param p2
	 * @param p3
	 * @param p4
	 * @param isPt
	 * @return
	 */
	public static boolean findIntersectionPoint(Point2D p1, Point2D p2,
			Point2D p3, Point2D p4, Point2D isPt) {
		double q = (p1.getY() - p2.getY()) * (p4.getX() - p3.getX())
				- (p1.getX() - p3.getX()) * (p4.getY() - p3.getY());
		double d = (p2.getX() - p1.getX()) * (p4.getY() - p4.getY())
				- (p2.getY() - p1.getY()) * (p4.getX() - p4.getX());
		if (0 == d) {
			return false;
		}
		double r = q / d;
		q = (p1.getY() - p3.getY()) * (p2.getX() - p1.getX())
				- (p1.getX() - p3.getX()) * (p2.getY() - p1.getY());
		double s = q / d;
		if (r > 1 || r < 0 || s > 1 || s < 0) {
			return false;
		}
		double x = p1.getX() + r * (p2.getX() - p1.getX());
		double y = p1.getY() + r * (p2.getY() - p1.getY());
		isPt.setLocation(x, y);
		return true;

	}

	/**
	 * Return the intersection pts of two segments defined by ln1, ln2
	 * 
	 * http://www.javaworld.com/jw-04-2001/jw-0406-jmf1.html?page=5
	 * http://local.
	 * wasp.uwa.edu.au/~pbourke/geometry/pointline/DistancePoint.java
	 * 
	 * @param pt1
	 * @param pt2
	 * @param pt3
	 * @param pt4
	 * @return
	 */
	public static boolean findIntersectionPoint(Line2D.Double ln1,
			Line2D.Double ln2, Point2D isPt) {
		return findIntersectionPoint(ln1.getP1(), ln1.getP2(), ln2.getP1(), ln2
				.getP2(), isPt);
	}

	public static int[] genNRand(int N, int n) {
		int[] a = new int[N];
		for (int i = 0; i < N; i++) {
			a[i] = i;
		}
		for (int i = N - 1; i > 0; i--) {
			int index = Global.r.nextInt(i);
			int tmp = a[index];
			a[index] = a[i];
			a[i] = tmp;
		}
		int[] b = new int[n];
		System.arraycopy(a, 0, b, 0, n);
		return b;
	}

	public static void main(String[] args) {
		int[] a = new int[100];
		for (int i = 0; i < 10; i++) {
			a = genNRand(10000, 100);
		}
		long s = System.currentTimeMillis();
		for(int i = 0; i < 10; i++){
			a = genNRand(10000, 100);
		}
		long e = System.currentTimeMillis();
		System.out.println("Time used: " + (e-s));
		for(int i = 0; i < 100; i++){
			System.out.print(a[i] + ",");
			if((i+1) % 10 == 0){
				System.out.println();
			}
		}
	}
	
	public static void shuffle(int[] a){
		for (int i = a.length - 1; i > 0; i--) {
			int index = Global.r.nextInt(i);
			int tmp = a[index];
			a[index] = a[i];
			a[i] = tmp;
		}
	}
}
